package com.tiger.cloud.filter;

import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.tiger.cloud.auth0.jwt.TokenGenerator;
import com.tiger.cloud.auth0.jwt.interfaces.Claim;
import com.tiger.cloud.common.mapper.JsonMapper;
import com.tiger.cloud.util.CookieManager;
import com.tiger.cloud.util.DateTimeUtil;
import com.tiger.cloud.util.IPUtil;
import com.tiger.cloud.util.MagicConstants;

/**
 * @ClassName: LogAspect
 * @Description: 日志记录AOP实现
 */
@Aspect
@Component
public class LogAspect {

	private static final Logger logger = Logger.getLogger(LogAspect.class);

	private String requestPath = null; // 请求地址
	private Long loginId = null; // 用户名
	private String loginUserMobile = null; // 用户名
	private String loginUserToken = null; // 用户名
	private String requestIP = null; // IP
	private Object inputRequestParams = null; // 传入参数
	private Object inputContentParams = null; // 传入参数
	private Object outputParams = null; // 存放输出结果
	private long startTimeMillis = 0; // 开始时间
	private long endTimeMillis = 0; // 结束时间

	@Pointcut("execution(* com.tiger.cloud.controller.crm.*.*(..))")  
	private void controllerAspect() {
	}

	/**
	 * 
	 * @Title：doBeforeInServiceLayer
	 * @Description: 方法调用前触发 记录开始时间
	 * @param joinPoint
	 */
	@Before("controllerAspect()")
	public void doBeforeInServiceLayer(JoinPoint joinPoint) {
		startTimeMillis = System.currentTimeMillis(); // 记录方法开始执行的时间
	}

	/**
	 * 
	 * @Title：doAfterInServiceLayer
	 * @Description: 方法调用后触发 记录结束时间
	 * @param joinPoint
	 */
	@After("controllerAspect()")
	public void doAfterInServiceLayer(JoinPoint joinPoint) {
		endTimeMillis = System.currentTimeMillis(); // 记录方法执行完成的时间
		this.printOptLog();
	}

	 /**
     * 方法有异常时的操作
     */
    @AfterThrowing("controllerAspect()")
    public void doAfterThrow(){
        System.out.println("例外通知-----------------------------------");
    }
	
	/**
	 * 
	 * @Title：doAround
	 * @Description: 环绕触发
	 * @param pjp
	 * @return
	 * @throws Throwable
	 */
	@Around("controllerAspect()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		RequestAttributes ra = RequestContextHolder.getRequestAttributes();
		ServletRequestAttributes sra = (ServletRequestAttributes) ra;
		HttpServletRequest request = sra.getRequest();

		String token = request.getHeader(MagicConstants.User_Token);
		if (StringUtils.isEmpty(token)) {
			token = request.getParameter(MagicConstants.User_Token);
		}
		if (StringUtils.isEmpty(token)) {
			token = new CookieManager(request, null).getCookie(MagicConstants.User_Token);
		}
		if (!StringUtils.isEmpty(token)) {
			loginUserToken=token;
			Map<String, Claim> datas = TokenGenerator.getClaims(token);
			loginId = datas.get(MagicConstants.SESSION_USER_ID).asLong();
			loginUserMobile = datas.get(MagicConstants.SESSION_USER_MOBILE).asString();
		}
		requestPath = request.getRequestURI();
		if(!request.getServletPath().equals("/file")){
			//inputContentParams= IOUtils.toString(request.getInputStream());	 
		}
		requestIP = IPUtil.getIpAddress(request);
		// 获取输入参数
		inputRequestParams = request.getParameterMap();
		// 获取请求地址
		outputParams = pjp.proceed();// result的值就是被拦截方法的返回值
		return outputParams;
	}

	private void printOptLog() {
//		StringBuilder sb = new StringBuilder();
//		sb.append("---------------------------------------##################-----------------------------------------------\n");
//		sb.append("  user:      loginId: [" + loginId + "] loginUserMobile：["+loginUserMobile+"] loginUserToken："+loginUserToken+"\n");
//		sb.append("  url:       " + requestPath + "\n");
//		sb.append("  op_time:   " + DateTimeUtil.formatDateTimetoString(new Date(startTimeMillis)) + "\n");
//		sb.append("  pro_time:  " + (endTimeMillis - startTimeMillis) + "ms " + "\n");
//		sb.append("  ip:        " + requestIP + "\n");
//		sb.append("  inputRequestParams:   " +  JsonMapper.nonEmptyMapper().toJson(inputRequestParams) + "\n");
//		sb.append("  inputContentParams:   " + JsonMapper.nonEmptyMapper().toJson(inputContentParams)+ "\n");
//		sb.append("  result:               " + JsonMapper.nonEmptyMapper().toJson(outputParams) + "\n");
//		sb.append("---------------------------------------##################-----------------------------------------------\n");
//		String msg = "user：" + loginId + "  url：" + requestPath + "; op_time："
//				+ DateTimeUtil.formatDateTimetoString(new Date(startTimeMillis)) + "; pro_time："
//				+ (endTimeMillis - startTimeMillis) + "ms ;" + " ip：" + requestIP + "; inputRequestParams："
//				+ JsonMapper.nonEmptyMapper().toJson(inputRequestParams) + "; inputRequestParams："
//				+ JsonMapper.nonEmptyMapper().toJson(inputContentParams) + ";" + "\n result："
//				+ JsonMapper.nonEmptyMapper().toJson(outputParams);
		//logger.info(sb.toString());
	}
}